package com.demo.service.app.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.demo.service.app.dao.MovieDao;
import com.demo.service.app.pojo.MovieEntity;
import com.demo.service.app.service.MovieService;
import com.demo.service.app.util.JsoupUtil;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class MovieServiceImpl implements MovieService {
    private String baseUrl = "https://ssr1.scrape.center";

    @Autowired
    private JsoupUtil jsoupUtil;

    @Autowired
    private MovieDao movieDao;
    @Override
    public void readMovie() {
        //处理首页，获取分页信息
        int totalPage = queryPage(baseUrl);

        List<MovieEntity> movieList = new ArrayList<>();
        //根据总页数分别对每页进行处理
        for (int i=1; i<=totalPage; i++){
            String pageUrl = baseUrl + "/page/" + i;
            movieList.addAll(parseList(pageUrl));
            //批量提交
            if (i % 10 ==0){
                movieDao.insertBatch(movieList);
                movieList.clear();
            }
        }
        //提交剩余部分
        if (CollUtil.isNotEmpty(movieList)){
            movieDao.insertBatch(movieList);
        }
    }
    private int queryPage(String firstPage){
        Document doc = jsoupUtil.read(firstPage);
        Element page = doc.getElementsByAttributeValue("id", "index").last();
        Element lastPage = page.getElementsByTag("li").last();
        String totalPage = lastPage.getElementsByTag("a").text();
        return Integer.parseInt(totalPage);
    }

    /**
     * 列表页解析
     * @param pageUrl 列表页地址
     * @return
     */
    private List<MovieEntity> parseList(String pageUrl){
        List<MovieEntity> list = new ArrayList<>();
        Document doc = jsoupUtil.read(pageUrl);
        //读取每页的列表信息
        Element content = doc.getElementsByAttributeValue("id", "index").first();
        Elements elements = content.getElementsByClass("item");
        //读取每项的详情
        elements.forEach(e -> list.add(parseDetail(e)));
        return list;
    }

    /**
     * 内容解析
     * @param element 单条数据
     * @return
     */
    private MovieEntity parseDetail(Element element){
        MovieEntity movie = new MovieEntity();
        //每条数据分为左中右，左边为图片，中间为详细信息，右边为分数
        Elements elRow = element.getElementsByClass("el-card__body").first()
                .getElementsByClass("el-row").first().children();
        //读取各项信息
        Element body = elRow.get(1);
        Element foot = elRow.get(2);

        Element nameEle = body.getElementsByTag("a").first();
        movie.setMovieLink(baseUrl + nameEle.attr("href"));
        String[] fullName = nameEle.getElementsByTag("h2").first().text().split("-");
        movie.setMovieName(fullName[0].trim());
        movie.setEnName(fullName[1].trim());

        Elements categories = body.getElementsByClass("categories").first().getElementsByTag("span");
        StringBuilder sb = new StringBuilder();
        categories.forEach(s -> sb.append(s.text()).append("、"));
        movie.setCategory(sb.substring(0, sb.length()-1));

        Elements infos = body.getElementsByClass("info");
        Elements infoSpan = infos.get(0).children();
        movie.setDistrict(infoSpan.get(0).text());
        String totalTime = infoSpan.get(2).text();
        movie.setTotalTime(Integer.parseInt(totalTime.substring(0, totalTime.length()-2).trim()));

        String showTimeSpan = infos.get(1).getElementsByTag("span").text();
        if (StrUtil.isNotEmpty(showTimeSpan)){
            String showDate = showTimeSpan.substring(0, showTimeSpan.length()-2).trim();
            LocalDate showTime = LocalDate.parse(showDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            movie.setShowTime(LocalDateTime.of(showTime, LocalTime.MIN));
        }

        String score = foot.children().first().text();
        movie.setScore(new BigDecimal(score));

        movie.setCreateTime(LocalDateTime.now());
        movie.setUpdateTime(LocalDateTime.now());

        return movie;
    }
}
